import axios from 'axios'

import type { AxiosInstance } from 'axios'
import type { PmRequestInterceptor, PmConfig } from './type'

import { ElLoading } from 'element-plus'

const DEFAULT_SHOW_LOADING = true

class pmRequest {
  instance: AxiosInstance
  interceptor?: PmRequestInterceptor
  loading?: any
  isShowLoading: boolean

  constructor(config: PmConfig) {
    // 1.创建axios的实例
    this.instance = axios.create(config)
    // 2.定义
    this.interceptor = config.interceptor
    this.isShowLoading = config.isShowLoading ?? DEFAULT_SHOW_LOADING
    // 每个实例传入的拦截器
    this.instance.interceptors.request.use(
      this.interceptor?.requestInterceptor,
      this.interceptor?.requestInterceptorCatch
    )
    this.instance.interceptors.response.use(
      this.interceptor?.responseInterceptor,
      this.interceptor?.responseInterceptorCatch
    )

    // 全局的拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // console.log('全局拦截器：请求成功拦截')
        if (this.isShowLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: '拼命加载中...',
            background: 'rgba(0, 0, 0, 0.5)'
          })
        }
        return config
      },
      (err) => {
        // console.log('全局拦截器：请求失败拦截')
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        // console.log('全局拦截器：响应成功拦截')
        // 移除loading
        this.loading?.close()

        const data = res.data
        if (data?.returnCode === '-1001') {
          // console.log('xx错误')
        } else {
          return res.data
        }
      },
      (err) => {
        // console.log('全局拦截器：响应失败拦截xxx')
        this.loading?.close()
        if (err.response.status === 404) {
          // console.log('404的错误~')
        }
        return err
      }
    )
  }

  // 单个请求的拦截
  request<T>(config: PmConfig<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      // 1.单独请求config处理
      if (config.interceptor?.requestInterceptor) {
        config = config.interceptor.requestInterceptor(config)
      }

      // 2.判断是否需要loading
      if (config.isShowLoading === false) {
        this.isShowLoading = config.isShowLoading
      }

      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 1.单个请求拦截的处理
          if (config.interceptor?.responseInterceptor) {
            res = config.interceptor.responseInterceptor(res)
          }
          // console.log(res)
          // 2.下一次请求前重置isShowLoading
          this.isShowLoading = DEFAULT_SHOW_LOADING
          resolve(res)
        })
        .catch((err) => {
          // 下一次请求前重置isShowLoading
          this.isShowLoading = DEFAULT_SHOW_LOADING
          reject(err)
          return err
        })
    })
  }

  get<T>(config: PmConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }

  post<T>(config: PmConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'POST' })
  }

  delete<T>(config: PmConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'DELETE' })
  }

  put<T>(config: PmConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'PUT' })
  }

  patch<T>(config: PmConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'PATCH' })
  }
}

export default pmRequest
